#include "stdafx.h"
#include "win_toolbar.h"
#include "h2image.h"
#include "h2log.h"
#include "rapidxml/rapidxml.hpp"

#pragma comment(lib,"comctl32.lib")


win_menu    toolbar_menu;


bool win_toolbar::set_button(int n, STRING::utf8 xml)
{
    rapidxml::xml_document<> doc;

    try{ doc.parse<0>((char*)*xml); }catch(...) {}

    int idx = n;

    for(rapidxml::xml_node<> *node = doc.first_node(); node; node = node->next_sibling(), ++idx)
    {
        STRING::utf8 nodename(node->name());
        if(0 != STRING::icmp(nodename, "button")) continue;

        if(idx < 0 || idx >= count()) idx = create_button();

        for(rapidxml::xml_attribute<> *attr = node->first_attribute(); attr; attr = attr->next_attribute())
        {
            STRING::utf8 name(attr->name());
            STRING::unicode value(STRING::utf8(attr->value()));

            if(0 == STRING::icmp(name, "text")) set_button_text(idx, *value);
            if(0 == STRING::icmp(name, "comment")) set_button_comment(idx, *value);
            if(0 == STRING::icmp(name, "command")) set_button_cmd(idx, *value);
            if(0 == STRING::icmp(name, "image"))
            {
                STRING::unicode iname = STRING::split(value, L";");
                set_button_image(idx, *iname, value.length()?_wtoi(*value):0);
            }
            if(0 == STRING::icmp(name, "type"))
            {
                if(0 == STRING::icmp(value, L"button")) set_button_type(idx, TBB_TYPE_BUTTON);
                else if(0 == STRING::icmp(value, L"splitter")) set_button_type(idx, TBB_TYPE_SPLITTER);
                else if(0 == STRING::icmp(value, L"drop")) set_button_type(idx, TBB_TYPE_DROP);
                else if(0 == STRING::icmp(value, L"menu")) set_button_type(idx, TBB_TYPE_MENU);
            }
        }
    }

    update();
    return true;
}






LRESULT win_toolbar::OnLeftDown(WORD x, WORD y, BOOL bCtrlDown, BOOL bShiftDown)
{
    for(int i = 0; i < _buttons.length(); ++i)
    {
        _buttons[i].press(x, y);
    }

    OnMouseMove(0, x, y);
    return 0;
}




LRESULT win_toolbar::OnLeftUp(WORD x, WORD y, BOOL bCtrlDown, BOOL bShiftDown)
{
    for(int i = 0; i < _buttons.length(); ++i)
    {
        _buttons[i].unpress(x, y);

        if(_buttons[i].is_clicked())
        {
            if(_buttons[i].type == TBB_TYPE_DROP || _buttons[i].type == TBB_TYPE_MENU)
            {
                toolbar_menu.destroy_window();
                if(toolbar_menu.reg_class() && toolbar_menu.create(NULL))
                {
                    SetFocus(toolbar_menu.get_handle());
                    POINT pt = {_buttons[i].rect.left,_buttons[i].rcbound.bottom};
                    ClientToScreen(_hWnd, &pt);
                    toolbar_menu.move_window(pt.x, pt.y, 0, 0, false);
                    toolbar_menu.setup(H2APP::data[0][*_buttons[i].command].utf8());
                }
            }
            else
            {
                if(_buttons[i].command.length()) H2APP::send_msg(*_buttons[i].command);
            }
            _buttons[i].reset();
        }
    }

    OnMouseMove(0, x, y);

    return 0;
}




LRESULT win_toolbar::OnMouseMove(DWORD dwKeys, WORD x, WORD y)
{
    HWND hCapture = GetCapture();
    RECT client;
    GetClientRect(_hWnd, &client);
    bool focus = (x >= client.left && x < client.right && y >= client.top && y < client.bottom);

    for(int i = 0; i < _buttons.length(); ++i)
    {
        _buttons[i].hover(x, y);
        if(_buttons[i].is_hovered() || _buttons[i].is_pressed()) focus = true;
    }


    if(focus)
    {
        if(hCapture != _hWnd) SetCapture(_hWnd);
    }
    else
    {
        if(hCapture == _hWnd) ReleaseCapture(); 
    }

    start_timer();

    return 0;
}




LRESULT win_toolbar::OnPaint()
{
    RECT rc;
    GetClientRect(_hWnd, &rc);

    Gdiplus::Bitmap membmp(rc.right - rc.left, rc.bottom - rc.top);
    Gdiplus::Graphics memgra(&membmp);
    memgra.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);

    draw_toolbar(memgra, rc);
    bool active = false;
    for(int i = 0; i < _buttons.length(); ++i)
    {
        switch(_buttons[i].type)
        {
        case TBB_TYPE_SPLITTER:
            draw_splitter(memgra, _buttons[i], _buttons[i].transparency());
            break;
        case TBB_TYPE_DROP:
            break;
        default:
            if(i < _buttons.length() - 1 && TBB_TYPE_DROP == _buttons[i+1].type)
            {
                draw_drop(memgra, _buttons[i+1], _buttons[i+1].transparency());
            }
            draw_button(memgra, _buttons[i], _buttons[i].transparency());
            break;
        }
        if(_buttons[i].active()) active = true;
    }

    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(_hWnd, &ps);
    Gdiplus::Graphics graphics(hdc);
    graphics.DrawImage(&membmp, 0, 0);
    EndPaint(_hWnd, &ps);

    if(!active) stop_timer();

    return 0;
}


void win_toolbar::update()
{
    _margin = max(2, (_size + 5) / 10);
    max_width = MAX_WIDTH;
    max_height = _size + _margin * 2; 

    RECT rc;
    GetClientRect(_hWnd, &rc);
    rc.left = _margin;
    rc.right = _margin + _size;
    rc.top = _margin;
    rc.bottom = _margin + _size;
    for(int i = 0; i < _buttons.length(); ++i)
    {
        memcpy(&_buttons[i].rcbound, &rc, sizeof(rc));
        memcpy(&_buttons[i].rect, &rc, sizeof(rc));

       switch(_buttons[i].type)
        {
        case TBB_TYPE_DROP:
            _buttons[i].rcbound.right = rc.left + max(4, min(16, _size / 4));
            if(i>0) _buttons[i].rcbound.left = _buttons[i-1].rcbound.left;
            _buttons[i].rect.right = _buttons[i].rcbound.right;
            break;
        case TBB_TYPE_SPLITTER:
            _buttons[i].rcbound.right = rc.left + max(4, min(8, _size / 8));
            _buttons[i].rect.right = _buttons[i].rcbound.right - 1;
            _buttons[i].rect.left += 1;
            break;
        default:
            _buttons[i].rect.left += _margin / 2;
            _buttons[i].rect.top += _margin / 2;
            _buttons[i].rect.right -= _margin / 2;
            _buttons[i].rect.bottom -= _margin / 2;
            break;
        }

        rc.left = _buttons[i].rcbound.right;
        rc.right = rc.left + _size;
    }

    InvalidateRect(_hWnd, NULL, TRUE);
}


void win_toolbar::draw_toolbar(Gdiplus::Graphics& g, RECT& rc)
{
    // draw background
    H2IMG::painter()->draw_background(g, rc, 100);
}




void win_toolbar::draw_button(Gdiplus::Graphics& g, button_base& button, int transparency)
{
    if(transparency) 
    {
        if(button.is_pressed())
        {
            H2IMG::painter()->draw_selected(g, button.rcbound, transparency * 2 / 3);
        }
        else
        {
            H2IMG::painter()->draw_highlight(g, button.rcbound, transparency * 2 / 3);
        }
        H2IMG::painter()->draw_edge(g, button.rcbound, transparency * 2 / 3);
    }

    RECT rcText, rcImage;
    bool bText = false, bImage = false;

    memcpy(&rcImage, &button.rect, sizeof(rcImage));
    memcpy(&rcText, &rcImage, sizeof(RECT));

    H2IMG::painter()->set_text_align(0);
    H2IMG::painter()->set_line_align(0);

    int iTxtSize = rcText.bottom - rcText.top;

    switch(_style)
    {
    case TB_STYLE_TEXT_ONLY:
        bText = true;
        bImage = false;
        break;
    case TB_STYLE_IMG_ONLY:
        bText = false;
        bImage = true;
        break;
    case TB_STYLE_SMALL_TEXT:
        if(_style == TB_STYLE_SMALL_TEXT) iTxtSize = (rcText.bottom - rcText.top) / 5;
    case TB_STYLE_MED_TEXT:
        if(_style == TB_STYLE_MED_TEXT) iTxtSize = (rcText.bottom - rcText.top) / 4;
    case TB_STYLE_LARGE_TEXT:
        if(_style == TB_STYLE_LARGE_TEXT) iTxtSize = (rcText.bottom - rcText.top) / 3;
    default:
        bText = true;
        bImage = true;
        rcImage.bottom -= iTxtSize;
        rcImage.left = (rcImage.left + rcImage.right - rcImage.bottom + rcImage.top) / 2;
        rcImage.right = rcImage.left + rcImage.bottom - rcImage.top;
        rcText.top = rcImage.bottom;
        break;
    }


    if(bImage)
    {
        H2IMG::painter()->draw_image(g, H2IMG::bitmap(button.image), rcImage, 70 + transparency *3 / 10);
    }

    if(bText)
    {
        H2IMG::painter()->set_font_size(iTxtSize);
        H2IMG::painter()->draw_text(g, rcText, *button.title, 100);
    }

}




void win_toolbar::draw_drop(Gdiplus::Graphics& g, button_base& button, int transparency)
{
    H2IMG::painter()->draw_background(g, button.rect, 100);

    if(transparency) 
    {
        if(button.is_pressed())
        {
            H2IMG::painter()->draw_selected(g, button.rcbound, transparency * 2 / 3);
        }
        else
        {
            H2IMG::painter()->draw_highlight(g, button.rcbound, transparency * 2 / 3);
        }
        H2IMG::painter()->draw_edge(g, button.rect, transparency * 2 / 3);
    }

    H2IMG::painter()->draw_edge(g, button.rect, 100);

    int x1 = (button.rect.left + button.rect.right) / 2; 
    int x2 = x1 -  (button.rect.right - button.rect.left) / 3;
    int x3 = x1 +  (button.rect.right - button.rect.left) / 3;
    int y1 = (button.rect.top + button.rect.bottom) / 2 + (button.rect.right - button.rect.left) / 3; 
    int y2 = (button.rect.top + button.rect.bottom) / 2 - (button.rect.right - button.rect.left) / 3; 

    Gdiplus::Point points[] = { Gdiplus::Point(x1, y1), Gdiplus::Point(x2, y2), Gdiplus::Point(x3, y2) };
    Gdiplus::SolidBrush brush(Gdiplus::Color(155 + transparency, 0, 0, 0));
    g.FillPolygon(&brush, points, 3);
}



void win_toolbar::draw_splitter(Gdiplus::Graphics& g, button_base& button, int transparency)
{
    H2IMG::painter()->draw_background(g, button.rect, 100);
    H2IMG::painter()->draw_edge(g, button.rect, 100);

    RECT rcTmp;
    memcpy(&rcTmp, &button.rect, sizeof(rcTmp));
    for(int i = 1; i <= 5; i += 2)
    {
        rcTmp.top = (button.rect.top + button.rect.bottom) / 2 - i;
        rcTmp.bottom = (button.rect.top + button.rect.bottom) / 2 + i;
        if(rcTmp.top > button.rect.top) H2IMG::painter()->draw_edge(g, rcTmp, 100);
    }
}




void win_menu::update()
{
    // resize window 
    _margin = max(2, (_size + 1) / 3); 
    max_width = _margin * 4 + _size; max_height = _margin;
    H2IMG::painter()->set_font_size(_size);
    for(int i = 0; i < _buttons.length(); ++i)
    {
        int w = 0, h = 0;
        if(_buttons[i].type == TBB_TYPE_BUTTON)
        {
            H2IMG::painter()->measure_text(*_buttons[i].title, -1, &w, &h);
        }
        max_width = max(max_width, _margin * 6 + _size + w);
        max_height += _margin * 2 + _size;
    }

    max_height = _margin;
    for(int j = 0; j < _buttons.length(); ++j)
    {
        _buttons[j].rcbound.left = _margin;
        _buttons[j].rcbound.top = max_height;
        _buttons[j].rcbound.right = max_width - _margin;
        _buttons[j].rcbound.bottom = max_height + _size + _margin * 2;

        memcpy(&_buttons[j].rect, &_buttons[j].rcbound, sizeof(_buttons[j].rcbound));

        if(TBB_TYPE_SPLITTER == _buttons[j].type)
        {
            _buttons[j].rcbound.bottom = max_height + max(4, _margin);
            _buttons[j].rect.top = (_buttons[j].rcbound.top + _buttons[j].rcbound.bottom) / 2 - 1;
            _buttons[j].rect.bottom = (_buttons[j].rcbound.top + _buttons[j].rcbound.bottom) / 2 + 1;
        }

        max_height = _buttons[j].rcbound.bottom;
    }

    RECT rect;
    GetWindowRect(_hWnd, &rect);
    move_window(rect.left, rect.top, max_width, max_height);
    InvalidateRect(_hWnd, NULL, TRUE);
}


void win_menu::draw_toolbar(Gdiplus::Graphics& g, RECT& rc)
{
    // draw background
    H2IMG::painter()->draw_background(g, rc, 100);
    RECT rcMask = rc;
    rcMask.right = rcMask.left + _margin * 4 + _size;
    H2IMG::painter()->draw_mask(g, rcMask, 32);
}




void win_menu::draw_button(Gdiplus::Graphics& g, button_base& button, int transparency)
{
    if(transparency) 
    {
        if(button.is_pressed())
        {
            H2IMG::painter()->draw_selected(g, button.rcbound, transparency * 2 / 3);
        }
        else
        {
            H2IMG::painter()->draw_highlight(g, button.rcbound, transparency * 2 / 3);
        }
        H2IMG::painter()->draw_edge(g, button.rcbound, transparency * 2 / 3);
    }

    RECT rcText, rcImage;
    bool bText = false, bImage = false;

    memcpy(&rcImage, &button.rect, sizeof(rcImage));
    memcpy(&rcText, &rcImage, sizeof(RECT));

    H2IMG::painter()->set_text_align(0);
    H2IMG::painter()->set_line_align(0);

    int iTxtSize = rcText.bottom - rcText.top;

    bText = true;
    bImage = true;
    H2IMG::painter()->set_text_align(-1);
    memcpy(&rcText, &button.rcbound, sizeof(RECT));
    memcpy(&rcImage, &button.rect, sizeof(RECT));
    rcImage.right = rcImage.left + rcImage.bottom - rcImage.top;
    rcText.left = rcImage.right + _margin * 2;


    if(bImage)
    {
        H2IMG::painter()->draw_image(g, H2IMG::bitmap(button.image), rcImage, 70 + transparency *3 / 10);
    }

    if(bText)
    {
        H2IMG::painter()->set_font_size(_size);
        H2IMG::painter()->draw_text(g, rcText, *button.title, 100);
    }

}




void win_menu::draw_drop(Gdiplus::Graphics& g, button_base& button, int transparency)
{
    H2IMG::painter()->draw_background(g, button.rect, 100);

    if(transparency) 
    {
        if(button.is_pressed())
        {
            H2IMG::painter()->draw_selected(g, button.rcbound, transparency * 2 / 3);
        }
        else
        {
            H2IMG::painter()->draw_highlight(g, button.rcbound, transparency * 2 / 3);
        }
        H2IMG::painter()->draw_edge(g, button.rect, transparency * 2 / 3);
    }

    H2IMG::painter()->draw_edge(g, button.rect, 100);

    int x1 = (button.rect.left + button.rect.right) / 2; 
    int x2 = x1 -  (button.rect.right - button.rect.left) / 3;
    int x3 = x1 +  (button.rect.right - button.rect.left) / 3;
    int y1 = (button.rect.top + button.rect.bottom) / 2 + (button.rect.right - button.rect.left) / 3; 
    int y2 = (button.rect.top + button.rect.bottom) / 2 - (button.rect.right - button.rect.left) / 3; 

    Gdiplus::Point points[] = { Gdiplus::Point(x1, y1), Gdiplus::Point(x2, y2), Gdiplus::Point(x3, y2) };
    Gdiplus::SolidBrush brush(Gdiplus::Color(155 + transparency, 0, 0, 0));
    g.FillPolygon(&brush, points, 3);
}



void win_menu::draw_splitter(Gdiplus::Graphics& g, button_base& button, int transparency)
{
    H2IMG::painter()->draw_background(g, button.rect, 100);
    H2IMG::painter()->draw_edge(g, button.rect, 100);

    RECT rcTmp;
    memcpy(&rcTmp, &button.rect, sizeof(rcTmp));
    for(int i = 1; i <= 5; i += 2)
    {
        rcTmp.left = (button.rect.left + button.rect.right) / 2 - i;
        rcTmp.right = (button.rect.left + button.rect.right) / 2 + i;
        if(rcTmp.left > button.rect.left) H2IMG::painter()->draw_edge(g, rcTmp, 100);
    }
}

/*

void win_toolbar::draw_button(Gdiplus::Graphics& g, button_base& button)
{
    DWORD now = GetTickCount();
    RECT rcText, rcImage, rcButton;
    bool bText = false, bImage = false;

    memcpy(&rcButton, &_rect, sizeof(rcButton));
    rcButton.left += _margin;
    rcButton.top += _margin;
    rcButton.right -= _margin;
    rcButton.bottom -= _margin;

    int iTxtSize = rcButton.bottom - rcButton.top;
    H2IMG::painter()->set_text_align(0);
    H2IMG::painter()->set_line_align(0);

    if((_hover || _press))
    {
        if(_transparency < 100)
        {
            _transparency += (now - _tick) / 3;
            _transparency = min(100, max(_transparency, 0));
        }
    }
    else
    {
        if(_transparency > 0)
        {
            _transparency -= (now - _tick) / 3;
            _transparency = min(100, max(_transparency, 0));
        }
    }

    switch(_tb_style)
    {
    case TB_STYLE_TEXT_ONLY:
        bText = true;
        bImage = false;
        memcpy(&rcText, &rcButton, sizeof(RECT));
        break;
    case TB_STYLE_IMG_ONLY:
        bText = false;
        bImage = true;
        memcpy(&rcImage, &rcButton, sizeof(RECT));
        break;
    case TB_STYLE_SMALL_TEXT:
        if(_tb_style == TB_STYLE_SMALL_TEXT) iTxtSize = (rcButton.bottom - rcButton.top) / 5;
    case TB_STYLE_MED_TEXT:
        if(_tb_style == TB_STYLE_MED_TEXT) iTxtSize = (rcButton.bottom - rcButton.top) / 4;
    case TB_STYLE_LARGE_TEXT:
        if(_tb_style == TB_STYLE_LARGE_TEXT) iTxtSize = (rcButton.bottom - rcButton.top) / 3;
    default:
        bText = true;
        bImage = true;
        memcpy(&rcText, &rcButton, sizeof(RECT));
        memcpy(&rcImage, &rcButton, sizeof(RECT));
        rcImage.bottom -= iTxtSize;
        rcImage.left = (rcImage.left + rcImage.right - rcImage.bottom + rcImage.top) / 2;
        rcImage.right = rcImage.left + rcImage.bottom - rcImage.top;
        rcText.top = rcImage.bottom;
        break;
    case TB_STYLE_MENU:
        bText = true;
        bImage = true;
        H2IMG::painter()->set_text_align(-1);
        memcpy(&rcText, &rcButton, sizeof(RECT));
        memcpy(&rcImage, &_rect, sizeof(RECT));
        iTxtSize = rcText.bottom - rcText.top;
        rcImage.right = rcImage.left + rcImage.bottom - rcImage.top;
        rcText.left = rcImage.right + _margin * 2;
        break;
    }

    if(_transparency) 
    {
        if(_press)
        {
            H2IMG::painter()->draw_selected(g, _rect, _transparency * 2 / 3);
        }
        else
        {
            H2IMG::painter()->draw_highlight(g, _rect, _transparency * 2 / 3);
        }
        H2IMG::painter()->draw_edge(g, _rect, _transparency * 2 / 3);
    }

    if(bImage)
    {
        H2IMG::painter()->draw_image(g, H2IMG::bitmap(_imgid), rcImage, 70 + _transparency *3 / 10);
    }

    if(bText)
    {
        H2IMG::painter()->set_font_size(iTxtSize);
        H2IMG::painter()->draw_text(g, rcText, *_title, 100);
    }

    _tick = now;
}
    */



/*

void toolbar_button::draw(Gdiplus::Graphics& g)
{
    DWORD now = GetTickCount();
    RECT rcText, rcImage, rcButton;
    bool bText = false, bImage = false;

    memcpy(&rcButton, &_rect, sizeof(rcButton));
    rcButton.left += _margin;
    rcButton.top += _margin;
    rcButton.right -= _margin;
    rcButton.bottom -= _margin;

    int iTxtSize = rcButton.bottom - rcButton.top;
    H2IMG::painter()->set_text_align(0);
    H2IMG::painter()->set_line_align(0);

    if((_hover || _press))
    {
        if(_transparency < 100)
        {
            _transparency += (now - _tick) / 3;
            _transparency = min(100, max(_transparency, 0));\
        }
    }
    else
    {
        if(_transparency > 0)
        {
            _transparency -= (now - _tick) / 3;
            _transparency = min(100, max(_transparency, 0));
        }
    }

    switch(_tb_style)
    {
    case TB_STYLE_TEXT_ONLY:
        bText = true;
        bImage = false;
        memcpy(&rcText, &rcButton, sizeof(RECT));
        break;
    case TB_STYLE_IMG_ONLY:
        bText = false;
        bImage = true;
        memcpy(&rcImage, &rcButton, sizeof(RECT));
        break;
    case TB_STYLE_SMALL_TEXT:
        if(_tb_style == TB_STYLE_SMALL_TEXT) iTxtSize = (rcButton.bottom - rcButton.top) / 5;
    case TB_STYLE_MED_TEXT:
        if(_tb_style == TB_STYLE_MED_TEXT) iTxtSize = (rcButton.bottom - rcButton.top) / 4;
    case TB_STYLE_LARGE_TEXT:
        if(_tb_style == TB_STYLE_LARGE_TEXT) iTxtSize = (rcButton.bottom - rcButton.top) / 3;
    default:
        bText = true;
        bImage = true;
        memcpy(&rcText, &rcButton, sizeof(RECT));
        memcpy(&rcImage, &rcButton, sizeof(RECT));
        rcImage.bottom -= iTxtSize;
        rcImage.left = (rcImage.left + rcImage.right - rcImage.bottom + rcImage.top) / 2;
        rcImage.right = rcImage.left + rcImage.bottom - rcImage.top;
        rcText.top = rcImage.bottom;
        break;
    case TB_STYLE_MENU:
        bText = true;
        bImage = true;
        H2IMG::painter()->set_text_align(-1);
        memcpy(&rcText, &rcButton, sizeof(RECT));
        memcpy(&rcImage, &_rect, sizeof(RECT));
        iTxtSize = rcText.bottom - rcText.top;
        rcImage.right = rcImage.left + rcImage.bottom - rcImage.top;
        rcText.left = rcImage.right + _margin * 2;
        break;
    }

    if(_transparency) 
    {
        if(_press)
        {
            H2IMG::painter()->draw_selected(g, _rect, _transparency * 2 / 3);
        }
        else
        {
            H2IMG::painter()->draw_highlight(g, _rect, _transparency * 2 / 3);
        }
        H2IMG::painter()->draw_edge(g, _rect, _transparency * 2 / 3);
    }

    if(bImage)
    {
        H2IMG::painter()->draw_image(g, H2IMG::bitmap(_imgid), rcImage, 70 + _transparency *3 / 10);
    }

    if(bText)
    {
        H2IMG::painter()->set_font_size(iTxtSize);
        H2IMG::painter()->draw_text(g, rcText, *_title, 100);
    }

    _tick = now;
}


win_toolbar::win_toolbar(int style)
{
    _timer = 0;
    _pressed = false;
    _tb_style = style;
    priority = PIR_TOOLBAR;

    switch(style)
    {
    case TB_STYLE_MENU:
        _dwExStyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
        _dwStyle = WS_POPUP | WS_VISIBLE | TBSTYLE_TOOLTIPS | CCS_TOP | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_NODIVIDER;
        set_size(12);
        break;
    default:
        _dwExStyle = WS_EX_PALETTEWINDOW;
        _dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS |TBSTYLE_FLAT | CCS_TOP | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_NODIVIDER;
        max_width = MAX_WIDTH;
        set_size(40);
        break;
    }
}




int win_toolbar::set_button(int idx, int type, int imgid, const wchar_t* title, const wchar_t* comment, const wchar_t* cmd)
{
    int n = idx;
    if(n < 0 || n >= _buttons.length())
    {
        n = _buttons.create();
    }

    _buttons[n].set_image(imgid);
    _buttons[n].set_title(title, comment);
    _buttons[n].set_command(cmd);
    _buttons[n].set_tb_style(_tb_style);

    update_size();
    update_layout();
    InvalidateRect(_hWnd, NULL, TRUE);

    return n;
}



void win_toolbar::update_size()
{
    int x, y;
    switch(_tb_style)
    {
    case TB_STYLE_MENU:
        // resize window 
         _margin = max(2, (_size + 2) / 4); 
        x = _margin * 4 + _size; y = _margin;
        H2IMG::painter()->set_font_size(_size);
        for(int i = 0; i < _buttons.length(); ++i)
        {
            int w,h;
            H2IMG::painter()->measure_text(_buttons[i].get_title(), -1, &w, &h);
            x = max(x, _margin * 7 + _size + w);
            y += _margin * 2 + _size;
        }
        RECT rect;
        GetWindowRect(_hWnd, &rect);
        if((rect.right - rect.left) != x || (rect.bottom - rect.top) != (y + _margin * 2))
        {
            MoveWindow(_hWnd, rect.left, rect.top, x, y + _margin, FALSE);
        }
        break;

    default:
         _margin = max(2, (_size + 4) / 8); 
         max_height = _size + _margin * 2;
        break;
    }
}



void win_toolbar::update_layout()
{
    RECT rc;
    GetClientRect(_hWnd, &rc);
    int width = rc.right - rc.left, height = rc.bottom - rc.top;
    int x, y;

    switch(_tb_style)
    {
    case TB_STYLE_MENU:
        // re-layout
        x = _margin * 2; y = _margin;
        for(int i = 0; i < _buttons.length(); ++i)
        {
            _buttons[i].set_margin(_margin);
            _buttons[i].set_pos(_margin, y, width - (_margin * 2), _size + _margin * 2);
            y += _margin * 2 + _size;
        }
        break;

    default:
        // re-layout
        x = _margin; y = _margin;
        for(int i = 0; i < _buttons.length(); ++i)
        {
            _buttons[i].set_margin(_margin / 2);
            _buttons[i].set_pos(x - _margin / 2, y - _margin / 2, _size + _margin / 2 * 2, _size + _margin / 2 * 2);
            x += _margin + _size;
        }
        break;
    }
}


LRESULT win_toolbar::OnPaint()
{
    RECT rc;
    GetClientRect(_hWnd, &rc);

    Gdiplus::Bitmap membmp(rc.right - rc.left, rc.bottom - rc.top);
    Gdiplus::Graphics memgra(&membmp);
    memgra.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);

    bool active = false;

    if(memgra.GetLastStatus() == Gdiplus::Ok)
    {
        H2IMG::painter()->draw_background(memgra, rc, 100);

        switch(_tb_style)
        {
        case TB_STYLE_MENU:
            {
                RECT rcMask = rc;
                rcMask.right = rcMask.left + _margin * 4 + _size;
                H2IMG::painter()->draw_mask(memgra, rcMask, 32);
            }
            break;
        }

        for(int i = 0; i < _buttons.length(); ++i)
        {
            _buttons[i].draw(memgra);
            if(_buttons[i].active()) active = true;
        }
    }

    if(active)
    {
        start_timer();
    }
    else if(!active)
    {
        stop_timer();
    }

    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(_hWnd, &ps);
    Gdiplus::Graphics graphics(hdc);
    graphics.DrawImage(&membmp, 0, 0);
    EndPaint(_hWnd, &ps);
    return 0;
}


LRESULT win_toolbar::OnTimer(DWORD dwTimerID, TIMERPROC* pTimeProc)
{
    InvalidateRect(_hWnd, NULL, TRUE);
    return 0;
}




LRESULT win_toolbar::OnKillFocus(HWND hWndReceiveFocus)
{
    if(_tb_style == TB_STYLE_MENU) DestroyWindow(_hWnd);
    return win_base::OnKillFocus(hWndReceiveFocus);
}

*/